package com.qaml.mes.device.utils;

import cn.hutool.core.lang.UUID;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.PutObjectRequest;
import com.earth.user.AuthSsoContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

/**
 * @ClassName OssUploadFileUtil
 * @Description 文件上传工具类
 * @Author leikai
 * @Date 2023/11/27 9:52
 * @Version 1.0
 */
@Component
public class OssUploadFileUtil {

    private static OSSClient client = null;
    private static final Logger logger = Logger.getLogger(OssUploadFileUtil.class);
    @Value("${ossfile.domain:http://sass-mes.oss-cn-shenzhen.aliyuncs.com}")
    private String ossDomain;
    @Value("${mes.file.store.bucket:sass-mes}")
    private String ossBucket;

    @Value("${oss.endpoint:oss-cn-shenzhen.aliyuncs.com}")
    private String endpoint;
    @Value("${oss.accessKey:LTAI5tA4HQ4iQWvPzbPxtuwc}")
    private String accessKeyId;
    @Value("${oss.accessKeySecret:3htJsvhNbAuz0gaGEtd0DuCEEv8DHD}")
    private String accessKeysScret;


    private static OssUploadFileUtil INSTANCE;

    private static OssUploadFileUtil getInstance() {
        if (INSTANCE == null) {
            INSTANCE = SpringUtils.getBean(OssUploadFileUtil.class);
        }
        return INSTANCE;
    }

    /**
     * 获取阿里云oss服务器endpoint
     *
     * @return
     */
    public static String getOssDomain() {
        return getInstance().ossDomain;
    }

    /**
     * 获取阿里云oss服务器bucket
     *
     * @return
     */
    public static String getBucketName() {
        return getInstance().ossBucket;
    }


    /**
     * 获取文件上传路径
     *
     * @param dir,文件存放目录，前后不带"/"
     * @param fileName           需要添加文件后缀的!!!
     * @return
     */
    public static String getUploadPath(String dir, String fileName) {
        if (StringUtils.isBlank(dir)) {
            return dir;
        }
        SimpleDateFormat sf = new SimpleDateFormat("/yyyy/MM/");
        StringBuilder sb = new StringBuilder(dir);
        sb.append(sf.format(new Date()));
        sb.append(fileName);
        return sb.toString();
    }

    /**
     * 上传文件
     *
     * @param object   上传对象（File、InputStream、BufferedImage）
     * @param filePath
     * @return
     * @throws Exception
     */
    public static Boolean uploadFile(Object object, String filePath) {
        return uploadFile(getBucketName(), object, filePath);
    }


    /**
     * 上传文件
     *
     * @param file
     * @param filePath
     * @return
     */
    public static boolean uploadFile(String filePath, InputStream file) {
        return uploadFile(getBucketName(), file, filePath);
    }

    public static void deleteFile(String filePath) {
        client.deleteObject(getBucketName(), filePath);
    }


    /**
     * 执行上传文件操作
     *
     * @param bucketName
     * @param object
     * @param filePath
     * @return
     * @throws Exception
     */
    private static Boolean uploadFile(String bucketName, Object object, String filePath) {


        if (null == object || StringUtils.isBlank(filePath)) {
            return false;
        } else if (null == client) {
            initOssClient();
        }
        if (object instanceof File) {//上传文件
            client.putObject(new PutObjectRequest(bucketName, filePath, (File) object));
        } else if (object instanceof InputStream) {//上传文件流
            client.putObject(bucketName, filePath, (InputStream) object);
        } else if (object instanceof BufferedImage) {//止传图片流
            InputStream is = null;
            try {
                is = getImageStream((BufferedImage) object);
                client.putObject(bucketName, filePath, is);
            } catch (Exception ex) {
                logger.error(ex);
                return false;
            } finally {
                if (null != is) {
                    try {
                        is.close();
                    } catch (IOException ex) {
                        logger.error(ex);
                    }
                }
            }
        } else {
            return false;
        }
        return true;
    }


    private static InputStream getImageStream(BufferedImage bi) throws IOException {

        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        ImageOutputStream imOut;
        imOut = ImageIO.createImageOutputStream(bs);
        ImageIO.write(bi, "jpg", imOut);
        InputStream is = new ByteArrayInputStream(bs.toByteArray());
        return is;
    }

    public static File multipartFileToFile(MultipartFile multiFile) {
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        // 若须要防止生成的临时文件重复,能够在文件名后添加随机码
        try {
            File file = File.createTempFile(fileName, prefix);
            multiFile.transferTo(file);
            return file;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取文件后缀
     *
     * @param multiFile
     * @return
     */
    public static String getFileExtensionName(MultipartFile multiFile) {
        return Objects.requireNonNull(multiFile.getOriginalFilename()).substring(multiFile.getOriginalFilename().lastIndexOf("."));
    }


    /**
     * @param: FilenameExtension
     * @Return: java.lang.String
     * @Decription: 判断OSS服务文件上传时文件的contentType
     * @CreateDate: Created in 2018/12/11 17:19
     * @Modify:
     */
    private static String getcontentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpeg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpeg";
    }

    /**
     * 获取文件扩展名
     *
     * @param fileName
     * @return
     */
    public static String getExtensionName(String fileName) {
        if (StringUtils.isNotBlank(fileName)) {
            int dot = fileName.lastIndexOf('.');
            if ((dot > -1) && (dot < (fileName.length() - 1))) {
                return fileName.substring(dot + 1).toLowerCase();
            }
        }
        return fileName;
    }

    /**
     * 获取上传地址全路径
     *
     * @param path
     * @return
     */
    public static String getUploadFilePath(String path) {
        if (StringUtils.isBlank(path)) {
            return "";
        } else {
            if (path.matches(".+\\://.+")) {
                return path;
            } else {
                return getOssDomain() + path;
            }
        }
    }

    public static String fileUpload(MultipartFile file) {
        if (null == client) {
            initOssClient();
        }
        Long orgId = AuthSsoContext.getSsoLoginUser().getOrgId();
        String uuid = UUID.randomUUID().toString();
        PutObjectRequest request = new PutObjectRequest(getBucketName(), orgId + "/" + uuid, multipartFileToFile(file));
        client.putObject(request);
        Date date = DateUtils.addMonths(new Date(), 60);
        URL url = client.generatePresignedUrl(getBucketName(), orgId + "/" + uuid, date);
        return url.toString();
    }

    /**
     * 阿里云配置初始化
     */
    private synchronized static void initOssClient() {
        String endpoint = getInstance().endpoint;
        String accessKeyId = getInstance().accessKeyId;
        String accessKeySecret = getInstance().accessKeysScret;
        client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
    }


    /**
     * 获取文件上传路径
     *
     * @param dir,文件存放目录，前后不带"/"
     * @param fileName
     * @return
     */
    public static String getUploadPaths(String dir, String fileName) {
        if (StringUtils.isBlank(dir)) {
            return dir;
        }
        SimpleDateFormat sf = new SimpleDateFormat("/yyyy/MM/dd/");
        StringBuilder sb = new StringBuilder(dir);
        String date = sf.format(new Date());
        sb.append(date).append(System.nanoTime()).append("/").append(fileName);
        return sb.toString();
    }

    public static String getFullFileUrl(String path) {
        return OssUploadFileUtil.getOssDomain() + path;
    }
}